﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using DateGenerator;

namespace DateGeneratorTests
{
    [TestClass]
    public class DateGeneratorTests
    {
        private RandomDate _sut;
        private DateTime _pastLowerBoundary;
        private DateTime _pastUpperBoundary;
        private DateTime _futureUpperBoundary;
        private DateTime _futureLowerBoundary;

        [TestInitialize]
        public void TestSetUp() 
        {
           
            _sut = new RandomDate();

            _pastLowerBoundary = new DateTime(2010, 04, 22);
            _pastUpperBoundary = new DateTime(2010, 05, 01);

            _futureUpperBoundary = new DateTime(2020, 12, 30);
            _futureLowerBoundary = new DateTime(2020, 12, 20);     
        }

        [TestMethod]
        public void GenerateRandomeDate()
        {
            DateTime generatedDate = _sut.Generate();

            Assert.IsNotNull(generatedDate);
            Assert.AreEqual(typeof(DateTime), generatedDate.GetType());
        }

        [TestMethod]
        public void GenerateTestInPast()
        {
            _sut.UpperBoundary = DateTime.Today;

            DateTime generatedDate1 = _sut.Generate();
            DateTime generatedDate2 = _sut.Generate();

            Assert.IsTrue(DateTime.Today > generatedDate1);
            Assert.AreNotEqual(generatedDate1, generatedDate2);
        }        

        
        [TestMethod]
        public void GenerateTestInPast_With_Lower_And_Upper_Boundary()
        {
            //Define range of desired dates in the past
            //Our generator will create dates within these boundaries
            _sut.LowerBoundary = _pastLowerBoundary;
            _sut.UpperBoundary = _pastUpperBoundary;

            //Generates a date in the past, after LowerBoundary but before UpperBoundary
            DateTime generatedDate = _sut.Generate();           

            Assert.IsTrue(DateTime.Today > generatedDate);
            //Assert dates are within specified range
            Assert.IsTrue(_pastLowerBoundary <= generatedDate, "Generated date 1 is outside the lower boundary range. Generated Date: {0} Lower Boundary {1}", generatedDate, _pastLowerBoundary);
            Assert.IsTrue(_pastUpperBoundary >= generatedDate, "Generated date 1 is outside the upper boundary range. Generated Date: {0} Upper Boundary: {1}", generatedDate, _pastUpperBoundary);            
        }        

        [TestMethod]
        public void GenerateTestInFuture()
        {
            _sut.LowerBoundary = DateTime.Today;            

            DateTime futureDate1 = _sut.Generate();

            
            DateTime futureDate2 = _sut.Generate();

            Assert.IsTrue(DateTime.Today < futureDate1);
            Assert.AreNotEqual(futureDate1, futureDate2);
        }        

        [TestMethod]
        public void GenerateTestInFuture_With_Upper_And_Lower_Boundary() 
        {
            _sut.LowerBoundary = _futureLowerBoundary;
            _sut.UpperBoundary = _futureUpperBoundary;

            DateTime futureDate1 = _sut.Generate();
            
            //Assert date is in the future
            Assert.IsTrue(DateTime.Today < futureDate1);
           
            //Assert date is within the specified range
            Assert.IsTrue(futureDate1 >= _futureLowerBoundary, "The Generated date 1 is outside the lower boundary. Generated Date: {0} Lower Boundary: {1}", futureDate1, _futureLowerBoundary);
            Assert.IsTrue(futureDate1 <= _futureUpperBoundary, "The Generated date 1 is outside the upper boundary. Generated Date: {0} Upper Boundary: {1}", futureDate1, _futureLowerBoundary);
        }

        [TestMethod]
        public void Use_Past_Method_To_Get_Date_In_Past()
        {
            DateTime pastDate = _sut.Past();

            Assert.IsTrue(DateTime.Today > pastDate, "The condition was not met. The generated date {0} is not in the past.", pastDate.ToShortDateString());
        }

        [TestMethod]
        public void Use_Past_Method_With_Lower_Boundary()
        {
            _sut.LowerBoundary = _pastLowerBoundary;
            
            DateTime pastDate = _sut.Past();

            Assert.IsTrue(pastDate < DateTime.Today);
            Assert.IsTrue(_pastLowerBoundary < pastDate);
        }

        [TestMethod]
        public void Use_Future_Method_To_Get_Date_In_Future()
        {
            DateTime futureDate = _sut.Future();

            Assert.IsTrue(DateTime.Today < futureDate);
        }

        [TestMethod]
        public void Use_Future_Method_With_Upper_Boundary_To_Get_Date_In_Future()
        {
            _sut.UpperBoundary = _futureUpperBoundary;

            DateTime futureDate = _sut.Future();

            Assert.IsTrue(DateTime.Today < futureDate);
            Assert.IsTrue(futureDate < _futureUpperBoundary);
        }
        
/*        [TestMethod]
        public void Use_Invalid_Boundaries_Throw_Exception()
        {
            try
            {
                _sut.UpperBoundary = _pastLowerBoundary;
                _sut.LowerBoundary = _pastUpperBoundary;

                DateTime ShouldNeverBeAssigned = _sut.Generate();
            }
            catch(InvalidDateRangeException e)
            {
                
            }

        }*/
        
    }
}

